﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using Eneta.Portal.Common.Dto;

using Microsoft.SharePoint;

namespace Eneta.Portal.Common.Repository
{
    /// <summary>
    /// Class for blogs repository. Offers blogs querying and management methods.
    /// </summary>
    public class BlogRepository : NewsItemRepository 
    {
        private readonly UserProfileRepository _profileRepository;

        /// <summary>
        /// Initializes a new instance of the <see cref="BlogRepository"/> class.
        /// </summary>
        public BlogRepository(SPWeb web) : base(web)
        {
            _profileRepository = new UserProfileRepository(web);
        }

        /// <summary>
        /// Gets the blog by id.
        /// </summary>
        /// <param name="id">The id of blog.</param>
        public BlogDto GetBlogById(int id)
        {
            BlogDto blog = null;

            var sec = new SPSecurity.CodeToRunElevated(delegate
                {
                    using (var site = new SPSite(SiteId))
                    using (var web = site.OpenWeb("/uudised/blogid/"))
                    {
                        blog = GetBlogById(web, id);
                    }
                });
            SPSecurity.RunWithElevatedPrivileges(sec);
            return blog;
        }

        private BlogDto GetBlogById(SPWeb web, int id)
        {
            //var list = web.Lists["FeedSource"];
            var list = web.Lists["Lehed"];

            var queryString = "<Where><Eq><FieldRef Name='ID' /><Value Type='int'>{0}</Value></Eq></Where>";
            queryString = string.Format(queryString, id);

            var query = new SPQuery {Query = queryString, RowLimit = 1};
            var items = list.GetItems(query);

            if (items == null)
                return null;
            if (items.Count == 0)
                return null;

            var item = items[0];
            if (item == null)
                return null;

            var blog = CreateBlog(item);
            return blog;
        }

        public IList<BlogDto> GetUserBlogs(string userName, bool returnAll)
        {
            IList<BlogDto> blogs = null;

            var sec = new SPSecurity.CodeToRunElevated(delegate
            {
                using (var site = new SPSite(SiteId))
                using (var web = site.OpenWeb("/uudised/blogid/"))
                {
                    blogs = GetUserBlogs(web, userName, returnAll);
                }
            });
            SPSecurity.RunWithElevatedPrivileges(sec);
            return blogs;
        }

        private IList<BlogDto> GetUserBlogs(SPWeb web, string userName, bool returnAll)
        {
            var user = web.SiteUsers["liveid:" + userName];

            var queryString = "<Where><Eq><FieldRef Name='Owner' LookupId='True' /><Value Type='User'>{0}</Value></Eq></Where>";
            queryString = string.Format(queryString, user.ID);
            
            //var list = web.Lists["FeedSource"];
            var list = web.Lists["Lehed"];
            var query = new SPQuery();
            query.Query = queryString;

            var items = list.GetItems(query);
            var blogs = new List<BlogDto>();

            foreach(SPListItem item in items)
            {
                if (!returnAll)
                    if (item.ModerationInformation.Status != SPModerationStatusType.Approved)
                        continue;

                var blog = CreateBlog(item);
                blogs.Add(blog);
            }

            return blogs;
        }

        /// <summary>
        /// Gets the blog entry by id.
        /// </summary>
        /// <param name="id">The id of blog entry.</param>
        public BlogEntryDto GetBlogEntryById(int id)
        {
            BlogEntryDto entry = null;

            var sec = new SPSecurity.CodeToRunElevated(delegate
            {
                using (var site = new SPSite(SiteId))
                using (var web = site.OpenWeb("/uudised/blogid/"))
                {
                    entry = GetBlogEntryById(web, id);
                }
            });
            SPSecurity.RunWithElevatedPrivileges(sec);
            return entry;
        }

        private BlogEntryDto GetBlogEntryById(SPWeb web, int id)
        {
            //var list = web.Lists["FeedEntries"];
            var list = web.Lists["Lehed"];
            var item = QueryItemByFieldValue(list, "ID", id.ToString());
            if (item == null)
                return null;

            var entry = CreateBlogEntry(item);
            return entry;            
        }

        /// <summary>
        /// Gets the list of pending blogs.
        /// </summary>
        public IList<BlogDto> GetPendingBlogs()
        {
            var queryString = "<Where><And><Eq><FieldRef Name='_ModerationStatus' /><Value Type='ModStat'>{0}</Value></Eq>";
            queryString += "<Eq><FieldRef Name='ContentType' /><Value Type='Text'>Blog</Value></Eq></And></Where>";
            queryString += "<OrderBy><FieldRef Name='Modified' Ascending='False' /></OrderBy>";
            queryString = string.Format(queryString, Resources.ModerationStatusPending);
            return QueryBlogs(queryString);
        }

        /// <summary>
        /// Gets the list of unapproved blogs.
        /// </summary>
        public IList<BlogDto> GetUnapprovedBlogs()
        {
            var queryString = "<Where><And><Neq><FieldRef Name='_ModerationStatus' /><Value Type='ModStat'>{0}</Value></Neq>";
            queryString += "<Eq><FieldRef Name='ContentType' /><Value Type='Text'>Blog</Value></Eq></And></Where>";
            queryString += "<OrderBy><FieldRef Name='Modified' Ascending='False' /></OrderBy>";
            queryString = string.Format(queryString, Resources.ModerationStatusApproved);
            return QueryBlogs(queryString);
        }

        /// <summary>
        /// Gets the list of approved blogs.
        /// </summary>
        /// <param name="orderByField">The order by field.</param>
        public IList<BlogDto> GetApprovedBlogs(string orderByField)
        {
            var queryString = "<Where><And><Eq><FieldRef Name='_ModerationStatus' /><Value Type='ModStat'>{0}</Value></Eq>";
            queryString += "<Eq><FieldRef Name='ContentType' /><Value Type='Text'>Blog</Value></Eq></And></Where>";
            queryString += "<OrderBy><FieldRef Name='Title' Ascending='True' /></OrderBy>";
            queryString = string.Format(queryString, Resources.ModerationStatusApproved);
            return QueryBlogs(queryString);
        }        

        /// <summary>
        /// Gets the list of user blogs.
        /// </summary>
        /// <param name="userId">The user id.</param>
        public IList<BlogDto> GetUserBlogs(int userId)
        {
            IList<BlogDto> results = new List<BlogDto>();

            var sec = new SPSecurity.CodeToRunElevated(delegate
                {
                    using(var site = new SPSite(SiteId))
                    using(var web = site.OpenWeb("/uudised/blogid/"))
                    {
                        results = GetUserBlogs(web, userId);
                    }
                });
            SPSecurity.RunWithElevatedPrivileges(sec);

            return results;
        }
        private IList<BlogDto> GetUserBlogs(SPWeb web, int userId)
        {
            var queryString = "<Where><Eq><FieldRef Name='Owner' LookupId='True' /><Value Type='User'>{0}</Value></Eq></Where>";
            queryString = string.Format(queryString, userId);

            var list = web.Lists["Lehed"];
            var items = ExecuteQuery(list, queryString);
            var results = CreateBlogs(items);

            return results;
        }

        /// <summary>
        /// Approves the blog with given id.
        /// </summary>
        /// <param name="blogId">The blog id.</param>
        /// <param name="comment">The comment by moderator.</param>
        public void ApproveBlog(int blogId, string comment)
        {
            SetBlogStatus(blogId, SPModerationStatusType.Approved, comment);
        }

        /// <summary>
        /// Denies the blog with given id.
        /// </summary>
        /// <param name="blogId">The blog id.</param>
        /// <param name="comment">The comment by moderator.</param>
        public void DenyBlog(int blogId, string comment)
        {
            SetBlogStatus(blogId, SPModerationStatusType.Denied, comment);
        }

        private void SetBlogStatus(int blogId, SPModerationStatusType status, string comment)
        {
            var sec = new SPSecurity.CodeToRunElevated(delegate
                       {
                           using(var site = new SPSite(SiteId))
                           using(var web = site.OpenWeb("/uudised/blogid/"))
                           {
                               SetBlogStatus(web, blogId, status, comment);
                           }
                       });
            SPSecurity.RunWithElevatedPrivileges(sec);
        }

        private void SetBlogStatus(SPWeb web, int blogId, SPModerationStatusType status, string comment)
        {
            //var list = web.Lists["FeedSource"];
            var list = web.Lists["Lehed"];
            var item = list.GetItemById(blogId);

            item.ModerationInformation.Status = status;
            item.ModerationInformation.Comment = comment;
            item.Update();
        }

        /// <summary>
        /// Gets the list of unapproved blog entries.
        /// </summary>
        public PagedResult<BlogEntryDto> GetUnapprovedEntries()
        {
            var queryString = "<Where><Neq><FieldRef Name='_ModerationStatus' /><Value Type='ModStat'>{0}</Value></Neq></Where>";
            queryString += "<OrderBy><FieldRef Name='Modified' Ascending='False' /></OrderBy>";
            queryString = string.Format(queryString, Resources.ModerationStatusApproved);
            return QueryBlogEntries(queryString, 0, 0);
        }

        /// <summary>
        /// Gets the the list of pending blog entries.
        /// </summary>
        public PagedResult<BlogEntryDto> GetPendingEntries()
        {
            var queryString = "<Where><And><Eq><FieldRef Name='_ModerationStatus' /><Value Type='ModStat'>{0}</Value></Eq>";
            queryString += "<Eq><FieldRef Name='ContentType' /><Value Type='Text'>BlogEntry</Value></Eq></And></Where>";
            
            queryString += "<OrderBy><FieldRef Name='Modified' Ascending='False' /></OrderBy>";
            queryString = string.Format(queryString, Resources.ModerationStatusPending);
            return QueryBlogEntries(queryString,0,0);
        }
        
        /// <summary>
        /// Gets the list of approved blog entries.
        /// </summary>
        public PagedResult<BlogEntryDto> GetApprovedEntries(int page, int pageSize)
        {
            var queryString = "<Where><And><Eq><FieldRef Name='_ModerationStatus' /><Value Type='ModStat'>{0}</Value></Eq>";
            queryString += "<Eq><FieldRef Name='ContentType' /><Value Type='Text'>BlogEntry</Value></Eq></And></Where>";
            queryString += "<OrderBy><FieldRef Name='PublishDate' Ascending='False' /></OrderBy>";
            queryString = string.Format(queryString, Resources.ModerationStatusApproved);
            return QueryBlogEntries(queryString, page, pageSize);
        }

        /// <summary>
        /// Gets the list of approved blog entries.
        /// </summary>
        public PagedResult<BlogEntryDto> GetApprovedEntriesByBlog(int blogId, int page, int pageSize)
        {
            var queryString = "<Where><And><And><Eq><FieldRef Name='_ModerationStatus' /><Value Type='ModStat'>{0}</Value></Eq>";
            queryString += "<Eq><FieldRef Name='ContentType' /><Value Type='Text'>BlogEntry</Value></Eq></And>";
            queryString += "<Eq><FieldRef Name='Blog' LookupId='True' /><Value Type='Lookup'>{1}</Value></Eq>";
            queryString += "</And></Where>";
            queryString += "<OrderBy><FieldRef Name='PublishDate' Ascending='False' /></OrderBy>";
            queryString = string.Format(queryString, Resources.ModerationStatusApproved, blogId);
            return QueryBlogEntries(queryString, page, pageSize);
        }

        private IList<CommentDto> CreateComments(SPListItemCollection items, bool excludeUnapproved)
        {
            IList<CommentDto> result = new List<CommentDto>();
            if (items == null)
                return result;

            foreach(SPListItem item in items)
            {
                if (item == null)
                    continue;

                var comment = CreateComment(item);
                if (comment == null)
                    continue;

                if(comment.Parent != null)
                    if (comment.Parent.Status != SPModerationStatusType.Approved)
                        continue;
                result.Add(comment);
            }

            return result;
        }

        private CommentDto CreateComment(SPListItem item)
        {
            if (item == null)
                return null;

            if (item["FeedEntry"] == null)
                return CreateComment(item, null);

            var entryValue = new SPFieldLookupValue(item["FeedEntry"].ToString());
            var post = GetBlogEntryById(entryValue.LookupId);

            return CreateComment(item, post);
        }

        private CommentDto CreateComment(SPListItem item, BlogEntryDto post)
        {
            var comment = new CommentDto
                              {
                                  Id = item.ID,
                                  Modified = (DateTime) item["Modified"], 
                                  Created = (DateTime) item["Created"],
                                  Title = item.Title
                              };

            var authorFieldId = item.Fields.GetFieldByInternalName("Author").Id;
            var authorValue = new SPFieldUserValue(item.Web, item[authorFieldId].ToString());
            var author = authorValue.User;

            comment.OwnerName = author.Name;

            var profileRepository = new UserProfileRepository(item.Web);
            //var profileItem = author.GetUserProfile();
            var profileItem = profileRepository.GetUserProfileByProfileName(author.Name);
            if (profileItem != null)
                comment.OwnerProfileId = profileItem.Id;
            comment.Parent = post;

            var createdFieldId = item.Fields.GetFieldByInternalName("Created").Id;
            comment.Created = (DateTime)item[createdFieldId];
            if (item["Comment"] != null)
                comment.Body = item["Comment"].ToString();

            return comment;
        }

        /// <summary>
        /// Gets the blogs RSS as string.
        /// </summary>
        public string GetBlogsRss()
        {
            var title = "Eneta portaal: Blogid";
            var url = "http://www.eneta.ee/uudised/blogid/";
            var posts = GetApprovedEntries(1, 25);

            return CreateRss(title, url, posts.Results);            
        }

        /// <summary>
        /// Gets the blogs comments RSS as string.
        /// </summary>
        public string GetBlogCommentsRss()
        {
            var rss = string.Empty;

            var sec = new SPSecurity.CodeToRunElevated(delegate
                       {
                           using (var site = new SPSite(SiteId))
                           using (var web = site.OpenWeb("/uudised/blogid/"))
                           {
                               rss = GetBlogCommentsRss(web);
                           }
                       });
            SPSecurity.RunWithElevatedPrivileges(sec);

            return rss;
        }

        /// <summary>
        /// Gets the list of blogs comments.
        /// </summary>
        /// <param name="limit">The number of comments to return. 0 means return all.</param>
        /// <returns></returns>
        public IList<CommentDto> GetBlogComments(int limit)
        {
            IList<CommentDto> results = new List<CommentDto>();

            var sec = new SPSecurity.CodeToRunElevated(delegate
                           {
                               using(var site = new SPSite(SiteId))
                               using(var web = site.OpenWeb("/uudised/blogid/"))
                               {
                                   results = GetBlogComments(web, limit);
                               }
                           });
            SPSecurity.RunWithElevatedPrivileges(sec);

            return results;
        }

        private IList<CommentDto> GetBlogComments(SPWeb web, int limit)
        {
            var queryString = "<OrderBy><FieldRef Name='Created' Ascending='False' /></OrderBy>";
            var query = new SPQuery
            {
                Query = queryString,
                RowLimit = 50
            };

            var list = web.Lists["FeedEntriesComments"];
            var items = list.GetItems(query);
            var comments = CreateComments(items, true).Take(limit).ToList();

            return comments;
        }

        private string GetBlogCommentsRss(SPWeb web)
        {
            var title = "Eneta portaal: Blogide kommentaarid";
            var url = "http://www.eneta.ee/uudised/blogid/";

            var queryString = "<OrderBy><FieldRef Name='Created' Ascending='False' /></OrderBy>";
            var query = new SPQuery
                            {
                                Query = queryString, 
                                RowLimit = 25
                            };
            HttpContext.Current.Trace.Write("GetBlogCommentsRss: Getting comments");
            var list = web.Lists["FeedEntriesComments"];
            var items = list.GetItems(query);
            HttpContext.Current.Trace.Write("GetBlogCommentsRss: Comments received");
            var comments = CreateComments(items, true).Take(25).ToList();
            HttpContext.Current.Trace.Write("GetBlogCommentsRss: Comment objects created");
            
            var rss = CreateCommentsRss(title, url, comments);
            HttpContext.Current.Trace.Write("GetBlogCommentsRss: RSS created");

            return rss;
        }

        private string CreateRss(string title, string viewUrl, IEnumerable<BlogEntryDto> entries)
        {
            var builder = new StringBuilder(GetRssHeader(title, viewUrl));
            if(entries == null)
            {
                builder.Append(GetRssFooter());
                return builder.ToString();
            }

            foreach(var entry in entries)
            {
                if (entry == null)
                    continue;
                builder.Append("<item>");
                builder.Append("<title>");

                if (!string.IsNullOrEmpty(entry.Title))
                {
                    var utility = HttpContext.Current.Server;
                    //builder.Append(entry.Title.Replace("&", "&amp;"));
                    builder.Append(utility.HtmlEncode(entry.Title));
                }
                builder.Append("</title>\r\n");

                builder.Append("<link>");
                builder.Append("http://www.eneta.ee/uudised/blogid/Lehed/" + entry.FileName);                
                builder.Append("</link>\r\n");
                
                builder.Append("<comments>");
                builder.Append("http://www.eneta.ee/uudised/blogid/Lehed/" + entry.FileName);
                builder.Append(entry.ID.ToString());
                builder.Append("#comments</comments>\r\n");

                builder.Append("<pubDate>");
                builder.Append(entry.Date.ToString("r"));
                builder.Append("</pubDate>\r\n");

                builder.Append("<dc:creator>");
                builder.Append(entry.Author);
                builder.Append("</dc:creator>\r\n");

                builder.Append("<guid isPermaLink=\"false\">");
                builder.Append("http://www.eneta.ee/uudised/blogid/Lehed/" + entry.FileName);  
                builder.Append("</guid>\r\n");

                builder.Append("<content:encoded><![CDATA[");
                //builder.Append(RegExHelper.DetectAndReplaceUrls(post.Body));
                builder.Append(entry.Summary);
                builder.Append("]]></content:encoded>\r\n");

                //builder.Append("<wfw:commentRss>");
                //builder.Append("http://www.eneta.ee/foorum/Lehed/default.aspx?control=ViewMessages&amp;topic=");
                //builder.Append(entry.ID);
                //builder.Append("&amp;rss=1");
                //builder.Append("</wfw:commentRss>");

                
                builder.Append("<slash:comments>");
                builder.Append(entry.Comments.Count);
                builder.Append("</slash:comments>");

                builder.Append("</item>");
            }

            builder.Append(GetRssFooter());
            return builder.ToString();
        }

        private IList<BlogDto> QueryBlogs(string queryString)
        {
            return QueryBlogs(queryString, 0);
        }

        private IList<BlogDto> QueryBlogs(string queryString, int limit)
        {
            var blogs = new List<BlogDto>();
            Logger.LogInfo("QueryBlogs: " + queryString, "");
            var sec = new SPSecurity.CodeToRunElevated(
                delegate
                    {
                        using (var site = new SPSite(SiteId))
                        using (var web = site.OpenWeb("/uudised/blogid/"))
                        {
                            var list = web.Lists["Lehed"];
                            var items = ExecuteQuery(list, queryString,limit);
                            if (items == null)
                                return;

                            foreach(SPListItem item in items)
                            {
                                blogs.Add(CreateBlog(item));
                            }
                        }
                    });

            SPSecurity.RunWithElevatedPrivileges(sec);
            return blogs;
        }
        

        private PagedResult<BlogEntryDto> QueryBlogEntries(string queryString, int page, int pageSize)
        {
            var result = new PagedResult<BlogEntryDto>();

            var sec = new SPSecurity.CodeToRunElevated(
                delegate
                {
                    using (var site = new SPSite(SiteId))
                    using (var web = site.OpenWeb("/uudised/blogid/"))
                    {
                        var list = web.Lists["Lehed"];
                        var items = ExecuteQuery(list, queryString, 0);
                        if (items == null)
                            return;
                        if (items.Count == 0)
                            return;

                        result.Page = (page <= 0 ? 1 : page);
                        result.PageSize = (pageSize <= 0 ? items.Count : pageSize);
                        result.PageCount = (int)Math.Ceiling(items.Count / (decimal)result.PageSize);                        

                        var startRow = Math.Min((result.Page - 1) * result.PageSize, items.Count);

                        for (var i = startRow; i < Math.Min(startRow + result.PageSize, items.Count);  i++)
                        {
                            var entry = CreateBlogEntry(items[i]);
                            entry.Comments = GetBlogComments(web, entry);
                            result.Results.Add(entry);
                        }
                    }
                });

            SPSecurity.RunWithElevatedPrivileges(sec);
            return result;
        }

        private IList<BlogDto> CreateBlogs(SPListItemCollection blogItems)
        {
            var results = new List<BlogDto>();

            foreach (SPListItem blogItem in blogItems)
                results.Add(CreateBlog(blogItem));

            return results;
        }

        private BlogDto CreateBlog(SPListItem item)
        {
            if (item == null)
            {
                Logger.LogInfo("CreateBlog(): item is null", GetType().ToString());                
                return null;
            }
            var blog = new BlogDto();
            blog.ID = item.ID;
            blog.Title = item.Title;
            blog.Created = (DateTime) item["Created"];
            blog.Modified = (DateTime) item["Modified"];

            if (item.ModerationInformation != null)
            {
                blog.Status = item.ModerationInformation.Status;
                blog.StatusComment = item.ModerationInformation.Comment;
            }
            blog.LastModified = (DateTime)item["Modified"];

            //if (item["Url"] != null)
            //{
            //    var url = new SPFieldUrlValue(item["Url"].ToString());
            //    blog.Url = url.Url;
            //}

            //if (item["Description"] != null)
            //{
            //    blog.Description = item["Description"].ToString();
            //}

            if (item["URL"] != null)
            {
                var url = new SPFieldUrlValue(item["URL"].ToString());
                blog.Url = url.Url;
            }

            if (item["PublishingPageContent"] != null)
            {
                blog.Description = item["PublishingPageContent"].ToString();
            }

            if (item["FirstEntryDate"] != null)
            {
                blog.FirstEntryDate = (DateTime)item["FirstEntryDate"];
            }

            if (item["FileLeafRef"] != null)
            {
                blog.FileName = item["FileLeafRef"].ToString();
            }

            if (item["RssUrl"] != null)
            {
                var rssValue = new SPFieldUrlValue(item["RssUrl"].ToString());
                blog.RssUrl = rssValue.Url;
            }

            if(item["Owner"] != null)
            {
                var userValue = new SPFieldUserValue(item.ParentList.ParentWeb, item["Owner"].ToString());
                var user = userValue.User;

                if(user != null)
                {
                    var userName = user.LoginName;
                    blog.OwnerUserName = userName;
                    var profile = _profileRepository.GetUserProfileByUserName(userName);

                    if(profile != null)
                    {
                        blog.OwnerName = profile.UserName;
                        blog.OwnerProfileId = profile.Id;
                    }
                }
            }
            return blog;
            var queryString = "<Where><Eq><FieldRef Name='FeedSource' LookupId='True' /><Value Type='Lookup'>{0}</Value></Eq></Where>";
            queryString = string.Format(queryString, item.ID);

            var feedItems = ExecuteQuery(item.Web.Lists["Feeds"], queryString);
            if(feedItems != null)
                if(feedItems.Count > 0)
                {
                    var feedItem = feedItems[0];
                    if (feedItem["Link"] != null)
                    {
                        var linkValue = new SPFieldUrlValue(feedItem["Link"].ToString());
                        blog.RssUrl = linkValue.Url;
                    }

                    queryString = "<Where><Eq><FieldRef Name='Feed' LookupId='True' /><Value Type='Lookup'>{0}</Value></Eq></Where>";
                    queryString += "<OrderBy><FieldRef Name='Modified' Ascending='False' /></OrderBy>";
                    queryString = string.Format(queryString, feedItem.ID);

                    var entryItems = ExecuteQuery(item.Web.Lists["FeedEntries"], queryString, 1);
                    if(entryItems != null)
                        if(entryItems.Count > 0)
                        {
                            var entryItem = entryItems[0];
                            blog.EntryLastModified = (DateTime)entryItem["Modified"];
                        }
                }
            return blog;
        }

        public DateTime GetLastModifiedDate()
        {
            using (var site = new SPSite(SiteId))
            using (var web = site.OpenWeb("/uudised/blogid/"))
            {
                var queryString = "<OrderBy><FieldRef Name='Modified' Ascending='False' /></OrderBy>";
                var query = new SPQuery { Query = queryString, RowLimit = 1 };
                var lastChange = DateTime.MinValue;

                var list = web.Lists["Lehed"];
                var items = list.GetItems(query);

                if (items != null)
                    if (items.Count > 0)
                        lastChange = (DateTime)items[0]["Modified"];

                list = web.Lists["FeedEntriesComments"];
                items = list.GetItems(query);

                if (items != null)
                    if (items.Count > 0)
                    {
                        var lastComment = (DateTime)items[0]["Modified"];
                        if (lastComment > lastChange)
                            lastChange = lastComment;
                    }

                return lastChange;
            }
        }

        internal BlogEntryDto CreateBlogEntry(SPListItem item)
        {
            if (item == null)
            {
                Logger.LogInfo("CreateBlogEntry(): item is null", GetType().ToString());
                return null;
            }
            var web = item.ParentList.ParentWeb;
            var blogEntry = new BlogEntryDto
            {
                ID = item.ID,
                Title = item.Title,
                Created = (DateTime)item["Created"],
                Modified = (DateTime)item["Modified"]
            };

            if (item["PublishingPageContent"] != null)
            {
                blogEntry.Summary = item["PublishingPageContent"].ToString().Replace("&quot;", "\"");
            }

            if (item["PublishDate"] != null)
            {
                blogEntry.Date = (DateTime)item["PublishDate"];
            }

            if (item["Blog"] != null)
            {
                var blogValue = new SPFieldLookupValue(item["Blog"].ToString());
                var blog = GetBlogById(web, blogValue.LookupId);

                blogEntry.AuhtorId = blog.OwnerProfileId;
                blogEntry.Author = blog.OwnerName;
                blogEntry.BlogId = blog.ID;
                blogEntry.BlogName = blog.Title;

                blogEntry.OwnerProfileId = blog.OwnerProfileId;
                blogEntry.OwnerUserName = blog.OwnerUserName;
                blogEntry.ProfileId = blog.OwnerProfileId;
                blogEntry.BlogUrl = blog.FileName;
            }

            if (item["URL"] != null)
            {
                var url = new SPFieldUrlValue(item["URL"].ToString());
                blogEntry.Url = url.Url;
            }

            if (item["Keywords"] != null)
            {
                var keywords = new SPFieldLookupValueCollection(item["Keywords"].ToString());
                foreach (var keyword in keywords)
                {
                    var dto = new KeywordDto
                    {
                        Id = keyword.LookupId,
                        Title = keyword.LookupValue
                    };
                    blogEntry.Keywords.Add(dto);
                }
            }

            if (item["FileLeafRef"] != null)
            {
                blogEntry.FileName = item["FileLeafRef"].ToString();
            }


            blogEntry.Status = SPModerationStatusType.Pending;
            if (item.ModerationInformation != null)
            {
                blogEntry.Status = item.ModerationInformation.Status;
                blogEntry.StatusComment = item.ModerationInformation.Comment;
            }

            blogEntry.Comments = GetBlogComments(item.Web, blogEntry);
            return blogEntry;
        }

        internal BlogEntryDto CreateBlogEntry(SPListItem item, bool loadComments)
        {
            var entry = CreateBlogEntry(item);
            if (loadComments)
                entry.Comments = GetBlogComments(item.Web, entry);

            return entry;
        }

        private List<CommentDto> GetBlogComments(SPWeb web, BlogEntryDto post)
        {
            var comments = new List<CommentDto>();
            if (post == null)
                return comments;
            if (post.ID <= 0)
                return comments;

            var list = web.Lists["FeedEntriesComments"];

            var queryString = "<Where><Eq><FieldRef Name='FeedEntry' LookupId='True' /><Value Type='Lookup'>{0}</Value></Eq></Where>";
            queryString += "<OrderBy><FieldRef Name='Created' Ascending='True' /></OrderBy>";
            queryString = string.Format(queryString, post.ID);
            var query = new SPQuery { Query = queryString };

            var items = list.GetItems(query);
            if (items == null)
                return comments;
            if (items.Count == 0)
                return comments;

            foreach (SPListItem item in items)
            {
                var comment = CreateComment(item, post);
                comments.Add(comment);
            }
            return comments;
        }
    }
}